package student.mindmap.core.model;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import java.util.List;

import static org.junit.jupiter.api.Assertions.*;

class MindMapTreeStructureTest {
    private MindMap mindMap;

    @BeforeEach
    void buildTreeFromImage() {
        mindMap = new MindMap();
        mindMap.createNewMap("Java核心技术");

        // 构建第1章分支
        MindMapNode chapter1 = buildChapter("第1章 Java语言概述", mindMap.getRoot());
        buildSection(chapter1, "1.1 Java语言的诞生与发展");
        buildSection(chapter1, "1.2 Java语言的特点");
        buildSection(chapter1, "1.3 Java语言规范");
        buildSection(chapter1, "1.4 Java虚拟机");
        buildSection(chapter1, "1.5 Java程序的种类和结构");

        // 构建第2章分支
        MindMapNode chapter2 = buildChapter("第2章 Java语言开发环境", mindMap.getRoot());
        MindMapNode section21 = buildSection(chapter2, "2.1 Java开发工具");
        buildSubSection(section21, "2.1.1 JDK下载与安装");
        buildSubSection(section21, "2.1.2 设置JDK");
        buildSection(chapter2, "2.2 JDK帮助文档");
        buildSection(chapter2, "2.3 JDK的使用");

        // 构建第3章分支
        MindMapNode chapter3 = buildChapter("第3章 Java语言基础", mindMap.getRoot());
        MindMapNode section31 = buildSection(chapter3, "3.1 数据类型");
        buildSubSection(section31, "3.1.1 基本数据类型");
        buildSubSection(section31, "3.1.2 引用数据类型");
        buildSection(chapter3, "3.2 关键字和标识符");
        buildSection(chapter3, "3.3 变量");
        buildSection(chapter3, "3.4 常量");
        buildSection(chapter3, "3.5 运算符与表达式");
        buildSection(chapter3, "3.6 从键盘输入数据");
    }

    // 辅助方法：构建章节节点
    private MindMapNode buildChapter(String text, MindMapNode parent) {
        MindMapNode node = new MindMapNode(text);
        parent.addChild(node);
        mindMap.registerNode(node);
        return node;
    }

    // 辅助方法：构建小节节点
    private MindMapNode buildSection(MindMapNode parent, String text) {
        MindMapNode node = new MindMapNode(text);
        parent.addChild(node);
        mindMap.registerNode(node);
        return node;
    }

    // 辅助方法：构建子小节节点
    private MindMapNode buildSubSection(MindMapNode parent, String text) {
        return buildSection(parent, text); // 复用相同逻辑
    }

    // ================== 结构化验证 ==================
    @Test
    void testRootStructure() {
        // 验证根节点
        MindMapNode root = mindMap.getRoot();
        assertEquals("Java核心技术", root.getText());
        assertEquals(3, root.getChildren().size(), "应有3个一级章节");
    }

    @Test
    void testChapter1Structure() {
        // 验证第1章结构
        MindMapNode chapter1 = mindMap.getRoot().getChildren().getFirst();
        assertChapterContent(chapter1, "第1章 Java语言概述", 5,
                "[1.1, 1.2, 1.3, 1.4, 1.5]");

        // 验证1.1子结构
        MindMapNode section11 = chapter1.getChildren().getFirst();
        assertEquals("1.1 Java语言的诞生与发展", section11.getText());
        assertTrue(section11.getChildren().isEmpty(), "1.1不应有子节点");
    }

    @Test
    void testChapter2NestedStructure() {
        // 验证第2章嵌套结构
        MindMapNode chapter2 = mindMap.getRoot().getChildren().get(1);
        assertChapterContent(chapter2, "第2章 Java语言开发环境", 3,
                "[2.1, 2.2, 2.3]");

        // 验证2.1开发工具子节点
        MindMapNode section21 = chapter2.getChildren().getFirst();
        assertEquals(2, section21.getChildren().size(), "2.1应有2个子条目");
        assertChildrenTexts(section21,
                "2.1.1 JDK下载与安装", "2.1.2 设置JDK");
    }

    @Test
    void testChapter3DeepHierarchy() {
        // 验证第3章深度结构
        MindMapNode chapter3 = mindMap.getRoot().getChildren().get(2);
        assertChapterContent(chapter3, "第3章 Java语言基础", 6,
                "[3.1, 3.2, 3.3, 3.4, 3.5, 3.6]");

        // 验证3.1数据类型子节点
        MindMapNode section31 = chapter3.getChildren().getFirst();
        assertChildrenTexts(section31,
                "3.1.1 基本数据类型",
                "3.1.2 引用数据类型");
    }

    // ================== 自定义断言方法 ==================
    private void assertChapterContent(MindMapNode chapter,
                                      String expectedText,
                                      int expectedChildrenCount,
                                      String expectedChildrenSummary) {
        assertEquals(expectedText, chapter.getText());
        assertEquals(expectedChildrenCount, chapter.getChildren().size(),
                () -> chapter.getText() + "子节点数量异常");
        assertEquals(expectedChildrenSummary,
                chapter.getChildren().stream()
                        .map(MindMapNode::getText)
                        .map(s -> s.split(" ")[0]) // 提取编号部分
                        .toList()
                        .toString()
        );
    }

    private void assertChildrenTexts(MindMapNode parent, String... expectedTexts) {
        List<String> actualTexts = parent.getChildren().stream()
                .map(MindMapNode::getText)
                .toList();
        assertArrayEquals(expectedTexts, actualTexts.toArray());
    }
}